package com.kobeliu.controller;


import com.google.gson.Gson;
import com.kobeliu.api.mq.RabbitMQSMSConfig;
import com.kobeliu.base.BaseInfoProperties;
import com.kobeliu.pojo.Users;
import com.kobeliu.pojo.bo.RegistryLoginBO;
import com.kobeliu.pojo.mq.SMSContentQO;
import com.kobeliu.pojo.vo.UsersVO;
import com.kobeliu.result.GraceJSONResult;
import com.kobeliu.result.IMOOCJSONResult;
import com.kobeliu.result.ResponseStatusEnum;
import com.kobeliu.result.SMSSendResult;
import com.kobeliu.service.UsersService;
import com.kobeliu.utils.IPUtil;
import com.kobeliu.utils.JwtUtils;
import com.kobeliu.utils.SMSUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.management.remote.rmi._RMIConnection_Stub;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.UUID;

@RestController
@Slf4j
@RequestMapping("/passport")
public class PassportController extends BaseInfoProperties {

    @Autowired
    private SMSUtils smsUtils;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private UsersService usersService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RabbitTemplate.ConfirmCallback confirmCallback;

    @RequestMapping(method = RequestMethod.GET,path = "getSMSCode")
    public GraceJSONResult getSMSCode(String mobile, HttpServletRequest request){

        if(StringUtils.isBlank(mobile)){
            return GraceJSONResult.error();
        }

        //限制用户只能在60s内获取一次验证码
        //获取用户ip
        String userIp = IPUtil.getRequestIp(request);
        //redis中加锁 60s过期时间
        redis.setnx60s(MOBILE_SMSCODE+":"+userIp,mobile);
        String value = (int)((Math.random()*9+1)*100000)+"";

        if(mobile.equals("17802592360")){
            value = "123456";
        }

        // SMSSendResult smsSendResult = smsUtils.sendAliyunSMS(mobile, "", value);
        // 云短信有失败的风险，所以我们需要有重试的机制，和异步的任务
        // 即 当出现失败重试的情况，不能有阻塞，需要接着执行
        // 使用mq来进行重试机制以及异步任务
        SMSContentQO smsContentQO = new SMSContentQO();
        smsContentQO.setContent(value);
        smsContentQO.setMobile(mobile);

//        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
//            @Override
//            public void returnedMessage(ReturnedMessage returnedMessage) {
//
//                //exchange --> queue失败时会返回，返回的时所有的相关信息
//                log.info("失败时返回的消息是:{}",returnedMessage);
//            }
//        });

        rabbitTemplate.setConfirmCallback(confirmCallback);

        //生产者 生产一条消息 放入mq
        rabbitTemplate.convertAndSend(RabbitMQSMSConfig.SMS_EXCHANGE,RabbitMQSMSConfig.ROUTING_KEY_SMS_SEND_LOGIN,new Gson().toJson(smsContentQO));


        SMSSendResult smsSendResult = new SMSSendResult();
        smsSendResult.setStatus("OK");

        if("OK".equals(smsSendResult.getStatus())){
            //存入redis ，用于后续校验
            redis.set(MOBILE_SMSCODE+":"+mobile,value);

            log.info("======================================");
            log.info("Redis key:{}",MOBILE_SMSCODE+":"+mobile);
            log.info("Redis value:{}",value);
            log.info("======================================");
        }

        return GraceJSONResult.ok();

    }


    @RequestMapping(method = RequestMethod.POST,path = "login")
    public GraceJSONResult login(@Valid @RequestBody RegistryLoginBO registryLoginBO, HttpServletRequest request){

        String smsCode = registryLoginBO.getSmsCode();
        String mobile = registryLoginBO.getMobile();
        String redisCode = redis.get(MOBILE_SMSCODE+":"+mobile);

        //做校验
        //1.从redis中获取验证码进行校验进行匹配
        //2.根据mobile查询数据库，判断用户是否存在
        //2.1 若记录为空，则表示没有注册过，则需要注册信息入库
        //3.用户登陆注册以后，删除redis中的短信验证码
        //4.返回信息给前端
        if(StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(smsCode)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }

        //查询数据库，看用户是否存在
        Users users = usersService.queryByMobile(mobile);
        if(users == null){
            users = usersService.createUsers(mobile);
        }



        //存储Token到Redis
        //1.生成一个UserToken
//        String userToken = TOKEN_USER_PREFIX + SYMBOL_DOT + UUID.randomUUID().toString();
//        redis.set(REDIS_USER_TOKEN+":"+users.getId(),userToken);
        String body = new Gson().toJson(users);
        String jwt = jwtUtils.createJwtWithPrefix(body, 360000 * 30L, TOKEN_USER_PREFIX);

        // redis.setnx60s(REDIS_USER_TOKEN+":"+users.getId(),jwt);


        //删除redis的验证码
        redis.del(MOBILE_SMSCODE+":"+mobile);

        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(users,usersVO);
        usersVO.setUserToken(jwt);

        return GraceJSONResult.ok(usersVO);
    }

    @Transactional
    @RequestMapping(method = RequestMethod.POST,path = "logout")
    public GraceJSONResult logout(@RequestParam String userId, HttpServletRequest request){

        //根据userId删除redis中的分布式key
        String key = REDIS_USER_TOKEN+":"+userId;

        if(redis.keyIsExist(key)){
            redis.del(key);
        }

        return GraceJSONResult.ok();


    }
}
